﻿using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;
using MultiCommunication.ViewModels;
using System.Windows;
using NLog;
using System.Windows.Markup;
using NLog.LayoutRenderers;

namespace MultiCommunication.Models
{
    public enum Direct
    {
        Send,
        Rece
    }
    public class DataLog
    {
        public Direct _Direct { get; set; }
        public string? Message { get; set; }

        public DataLog(Direct direct, string message)
        {
            this._Direct = direct;
            this.Message = message;
        }
        public override string ToString()
        {
            return string.Format("[{0}] {1}", _Direct, Message);
        }
    }
    public partial class PortViewModel:ObservableObject
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        SerialPort serialPort;

        [ObservableProperty] ObservableCollection<DataLog> responses = new ObservableCollection<DataLog>();

        [ObservableProperty] string[] ports = SerialPort.GetPortNames(); //获取串口到ComboBox

        [ObservableProperty] string selectedPort; //ComboBox的SelectedItem

        [ObservableProperty] string sendData; //发送的数据

        [ObservableProperty] string connectButtonContent = "Connect"; //button内容

        [ObservableProperty] bool selectComEnable = true; //能否选择串口

        [ObservableProperty] bool isHexDisplay = false; //是否按16进制显示

        [ObservableProperty] bool isHexSend = false; //是否按16进制发送
        public PortViewModel()
        {
            serialPort = new SerialPort();
            if (Ports.Any())
            {
                SelectedPort = Ports[0];
            }
        }
        [RelayCommand]
        public void Connect()
        {
            try
            {
                if (!serialPort.IsOpen)
                {
                    serialPort = new SerialPort(SelectedPort, 9600, Parity.None, 8, StopBits.One);
                    serialPort.DataReceived += SerialPort_DataReceived;
                    serialPort.Open();
                    Logger.Info($"{SelectedPort}连接成功");
                    ConnectButtonContent = "Disconnect";
                    SelectComEnable = false;
                }
                else
                {
                    serialPort.Close();
                    ConnectButtonContent = "Connect";
                    Logger.Info($"{SelectedPort}断开连接");
                    SelectComEnable = true;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                return;
            }
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string response = serialPort.ReadLine();
            try
            {
                if (IsHexDisplay)//是否以16进制显示
                {
                    string[] parts = response.Split(" ",StringSplitOptions.RemoveEmptyEntries);
                    List<string> responseHex = new List<string>();
                    foreach(string p in parts)
                    {
                        byte b = Convert.ToByte(p, 16);//以空格分隔，单个转为16进制
                        responseHex.Add(b.ToString());
                    }
                    string receiveData = string.Join(" ",responseHex);
                    Application.Current.Dispatcher.Invoke(() => Responses.Add(new DataLog(Direct.Rece,receiveData)));//此处没有使用三目运算符
                }
                else
                {
                    Application.Current.Dispatcher.Invoke(() => Responses.Add(new DataLog(Direct.Rece, response)));
                }
            }
            catch (Exception ex) 
            {
                Logger.Error(ex.Message);
            }
        }

        [RelayCommand]
        public void Send()
        {
            if (serialPort.IsOpen)
            {
                serialPort.WriteLine(SendData);
                Responses.Add(new DataLog(Direct.Send, SendData));
            }
            else
            {
                Logger.Warn("请先连接COM");
            }
        }
    }
}
